package com.yycx.app.provider.service.impl;


import com.yycx.app.provider.integration.authenticator.IntegrationAuthenticator;
import com.yycx.app.provider.integration.model.IntegrationAuthenticationContext;
import com.yycx.app.provider.integration.model.IntegrationParams;
import com.yycx.common.base.utils.FlymeUtils;
import com.yycx.common.oauth2.OpenOAuth2ClientProperties;
import com.yycx.common.utils.ApiAssert;
import com.yycx.module.user.client.entity.AppAccount;
import com.yycx.common.security.OpenUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Optional;

/**
 * APP用户认证中心
 *
 * @author zyf
 */
@Slf4j
@Service
public class AppUserDetailsService implements UserDetailsService {

    @Autowired
    private HttpServletRequest httpServletRequest;

    @Autowired
    private OpenOAuth2ClientProperties clientProperties;

    private List<IntegrationAuthenticator> authenticators;

    @Autowired(required = false)
    public void setIntegrationAuthenticators(List<IntegrationAuthenticator> authenticators) {
        this.authenticators = authenticators;
    }

    /**
     * 认证中心名称
     */
    @Value("${spring.application.name}")
    private String AUTH_SERVICE_ID;

    @Override
    public UserDetails loadUserByUsername(String username) {
        IntegrationParams integrationAuthentication = Optional.ofNullable(IntegrationAuthenticationContext.get()).orElse(new IntegrationParams());
        integrationAuthentication.setAccountName(username);
        AppAccount account = this.authenticate(integrationAuthentication);
        if (FlymeUtils.isEmpty(account)) {
            ApiAssert.failure("用户不存在");
        }
        boolean accountNonLocked = true;
        boolean credentialsNonExpired = true;
        boolean enable = true;
        boolean accountNonExpired = true;
        String clientId = clientProperties.getOauth2().get("portal").getClientId();
        String headerClientId = httpServletRequest.getHeader("client_id");
        if (FlymeUtils.isNotEmpty(headerClientId)) {
            clientId = headerClientId;
        }
        return new OpenUser(clientId, account.getDomain(), account.getAccountId(), account.getCompanyId(), account.getUserId(), account.getAccount(), account.getPassword(), accountNonLocked, accountNonExpired, enable, credentialsNonExpired, "", "", account.getAccountType());
    }

    /**
     * 根据登录类型适配具体执行类
     */
    private AppAccount authenticate(IntegrationParams integrationAuthentication) {
        if (this.authenticators != null) {
            for (IntegrationAuthenticator authenticator : authenticators) {
                if (authenticator.support(integrationAuthentication)) {
                    return authenticator.authenticate(integrationAuthentication);
                }
            }
        }
        return null;
    }
}
